package test001;

import javax.swing.*;
import javax.swing.event.UndoableEditEvent;
import javax.swing.event.UndoableEditListener;
import javax.swing.filechooser.FileNameExtensionFilter;
import javax.swing.text.*;
import javax.swing.undo.CannotRedoException;
import javax.swing.undo.CannotUndoException;
import javax.swing.undo.UndoManager;
import java.awt.*;
import java.awt.event.*;
import java.io.*;

public class TextEditor extends JFrame {
    private JTextArea textArea;
    private JScrollPane scrollPane;
    private JFileChooser fileChooser;
    private UndoManager undoManager;
    private String currentFilePath;
    private Font currentFont;
    private Color currentColor;

    public TextEditor() {
        initComponents();
        setupFileMenu();
        setupEditMenu();
        setupFormatMenu();
        setupSearchMenu();
        setupListeners();
        setDefaultLookAndFeelDecorated(true);
        setTitle("简易文本编辑器");
        setSize(800, 600);
        setLocationRelativeTo(null);
        setDefaultCloseOperation(EXIT_ON_CLOSE);
        setVisible(true);
    }






    private void initComponents() {


        textArea = new JTextArea();
        textArea.setFont(new Font("宋体", Font.PLAIN, 12));
        currentFont = textArea.getFont();
        currentColor = textArea.getForeground();
        scrollPane = new JScrollPane(textArea);
        scrollPane.setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_ALWAYS);
        scrollPane.setHorizontalScrollBarPolicy(JScrollPane.HORIZONTAL_SCROLLBAR_AS_NEEDED);
        add(scrollPane, BorderLayout.CENTER);

//        fileChooser = new JFileChooser();
//        fileChooser.setFileFilter(new FileNameExtensionFilter("文本文件", "txt"));
//        fileChooser.setFileFilter(new FileNameExtensionFilter("所有文件", "*"));

        fileChooser = new JFileChooser();
        // 添加多个文件过滤器
        FileNameExtensionFilter textFilter = new FileNameExtensionFilter("文本文件", "txt");
        FileNameExtensionFilter allFilter = new FileNameExtensionFilter("所有文件", "*");
        fileChooser.addChoosableFileFilter(textFilter);
        fileChooser.addChoosableFileFilter(allFilter);
         //设置默认显示所有文件
        fileChooser.setFileFilter(allFilter);
        // 允许选择文件夹（可选）
        fileChooser.setFileSelectionMode(JFileChooser.FILES_AND_DIRECTORIES);


        undoManager = new UndoManager();
        textArea.getDocument().addUndoableEditListener(new UndoableEditListener() {
            @Override
            public void undoableEditHappened(UndoableEditEvent e) {
                undoManager.addEdit(e.getEdit());
            }
        });
    }

    private void setupFileMenu() {
        JMenuBar menuBar = new JMenuBar();
        JMenu fileMenu = new JMenu("文件");

        JMenuItem newMenuItem = new JMenuItem("新建");
        newMenuItem.addActionListener(e -> newFile());

        JMenuItem openMenuItem = new JMenuItem("打开");
        openMenuItem.addActionListener(e -> openFile());

        JMenuItem saveMenuItem = new JMenuItem("保存");
        saveMenuItem.addActionListener(e -> saveFile());

        JMenuItem saveAsMenuItem = new JMenuItem("另存为");
        saveAsMenuItem.addActionListener(e -> saveFileAs());

        JMenuItem exitMenuItem = new JMenuItem("退出");
        exitMenuItem.addActionListener(e -> System.exit(0));

        fileMenu.add(newMenuItem);
        fileMenu.add(openMenuItem);
        fileMenu.add(saveMenuItem);
        fileMenu.add(saveAsMenuItem);
        fileMenu.addSeparator();
        fileMenu.add(exitMenuItem);
        menuBar.add(fileMenu);
        setJMenuBar(menuBar);
    }

    private void setupEditMenu() {
        JMenuBar menuBar = getJMenuBar();
        JMenu editMenu = new JMenu("编辑");

        JMenuItem undoMenuItem = new JMenuItem("撤销");
        undoMenuItem.addActionListener(e -> undo());

        JMenuItem redoMenuItem = new JMenuItem("重做");
        redoMenuItem.addActionListener(e -> redo());

        JMenuItem cutMenuItem = new JMenuItem("剪切");
        cutMenuItem.addActionListener(e -> textArea.cut());

        JMenuItem copyMenuItem = new JMenuItem("复制");
        copyMenuItem.addActionListener(e -> textArea.copy());

        JMenuItem pasteMenuItem = new JMenuItem("粘贴");
        pasteMenuItem.addActionListener(e -> textArea.paste());

        JMenuItem selectAllMenuItem = new JMenuItem("全选");
        selectAllMenuItem.addActionListener(e -> textArea.selectAll());

        editMenu.add(undoMenuItem);
        editMenu.add(redoMenuItem);
        editMenu.addSeparator();
        editMenu.add(cutMenuItem);
        editMenu.add(copyMenuItem);
        editMenu.add(pasteMenuItem);
        editMenu.addSeparator();
        editMenu.add(selectAllMenuItem);
        menuBar.add(editMenu);
    }

    private void setupFormatMenu() {
        JMenuBar menuBar = getJMenuBar();
        JMenu formatMenu = new JMenu("格式");

        JMenuItem fontMenuItem = new JMenuItem("字体");
        fontMenuItem.addActionListener(e -> changeFont());

        JMenuItem colorMenuItem = new JMenuItem("颜色");
        colorMenuItem.addActionListener(e -> changeColor());

        JMenu lineSpacingMenu = new JMenu("行距");
        ButtonGroup lineSpacingGroup = new ButtonGroup();

        JRadioButtonMenuItem singleSpacing = new JRadioButtonMenuItem("单倍行距");
        singleSpacing.addActionListener(e -> setLineSpacing(1.0f));
        singleSpacing.setSelected(true);

        JRadioButtonMenuItem oneHalfSpacing = new JRadioButtonMenuItem("1.5倍行距");
        oneHalfSpacing.addActionListener(e -> setLineSpacing(1.5f));

        JRadioButtonMenuItem doubleSpacing = new JRadioButtonMenuItem("双倍行距");
        doubleSpacing.addActionListener(e -> setLineSpacing(2.0f));

        lineSpacingGroup.add(singleSpacing);
        lineSpacingGroup.add(oneHalfSpacing);
        lineSpacingGroup.add(doubleSpacing);

        lineSpacingMenu.add(singleSpacing);
        lineSpacingMenu.add(oneHalfSpacing);
        lineSpacingMenu.add(doubleSpacing);

        formatMenu.add(fontMenuItem);
        formatMenu.add(colorMenuItem);
        formatMenu.addSeparator();
        formatMenu.add(lineSpacingMenu);
        menuBar.add(formatMenu);
    }

    private void setupSearchMenu() {
        JMenuBar menuBar = getJMenuBar();
        JMenu searchMenu = new JMenu("搜索");

        JMenuItem findMenuItem = new JMenuItem("查找");
        findMenuItem.addActionListener(e -> findText());

        JMenuItem replaceMenuItem = new JMenuItem("替换");
        replaceMenuItem.addActionListener(e -> replaceText());

        searchMenu.add(findMenuItem);
        searchMenu.add(replaceMenuItem);
        menuBar.add(searchMenu);
    }

    private void setupListeners() {
        textArea.addKeyListener(new KeyAdapter() {
            @Override
            public void keyPressed(KeyEvent e) {
                if ((e.getKeyCode() == KeyEvent.VK_S) && ((e.getModifiersEx() & KeyEvent.CTRL_DOWN_MASK) != 0)) {
                    saveFile();
                    e.consume();
                } else if ((e.getKeyCode() == KeyEvent.VK_O) && ((e.getModifiersEx() & KeyEvent.CTRL_DOWN_MASK) != 0)) {
                    openFile();
                    e.consume();
                } else if ((e.getKeyCode() == KeyEvent.VK_Z) && ((e.getModifiersEx() & KeyEvent.CTRL_DOWN_MASK) != 0)) {
                    undo();
                    e.consume();
                } else if ((e.getKeyCode() == KeyEvent.VK_Y) && ((e.getModifiersEx() & KeyEvent.CTRL_DOWN_MASK) != 0)) {
                    redo();
                    e.consume();
                }
            }
        });
    }

    private void newFile() {
        if (checkUnsavedChanges()) {
            textArea.setText("");
            currentFilePath = null;
            setTitle("简易文本编辑器");
        }
    }

    private void openFile() {
        if (checkUnsavedChanges()) {
            int returnValue = fileChooser.showOpenDialog(this);
            if (returnValue == JFileChooser.APPROVE_OPTION) {
                File selectedFile = fileChooser.getSelectedFile();
                try (BufferedReader reader = new BufferedReader(new FileReader(selectedFile))) {
                    StringBuilder content = new StringBuilder();
                    String line;
                    while ((line = reader.readLine()) != null) {
                        content.append(line).append("\n");
                    }
                    textArea.setText(content.toString());
                    currentFilePath = selectedFile.getAbsolutePath();
                    setTitle("简易文本编辑器 - " + selectedFile.getName());
                } catch (IOException ex) {
                    JOptionPane.showMessageDialog(this, "无法打开文件: " + ex.getMessage(), "错误", JOptionPane.ERROR_MESSAGE);
                }
            }
        }
    }

    private void saveFile() {
        if (currentFilePath == null) {
            saveFileAs();
        } else {
            try (BufferedWriter writer = new BufferedWriter(new FileWriter(currentFilePath))) {
                writer.write(textArea.getText());
                JOptionPane.showMessageDialog(this, "文件已保存", "保存成功", JOptionPane.INFORMATION_MESSAGE);
            } catch (IOException ex) {
                JOptionPane.showMessageDialog(this, "无法保存文件: " + ex.getMessage(), "错误", JOptionPane.ERROR_MESSAGE);
            }
        }
    }

    private void saveFileAs() {
        int returnValue = fileChooser.showSaveDialog(this);
        if (returnValue == JFileChooser.APPROVE_OPTION) {
            File selectedFile = fileChooser.getSelectedFile();
            String filePath = selectedFile.getAbsolutePath();
            if (!filePath.toLowerCase().endsWith(".txt")) {
                selectedFile = new File(filePath + ".txt");
            }
            try (BufferedWriter writer = new BufferedWriter(new FileWriter(selectedFile))) {
                writer.write(textArea.getText());
                currentFilePath = selectedFile.getAbsolutePath();
                setTitle("简易文本编辑器 - " + selectedFile.getName());
                JOptionPane.showMessageDialog(this, "文件已保存", "保存成功", JOptionPane.INFORMATION_MESSAGE);
            } catch (IOException ex) {
                JOptionPane.showMessageDialog(this, "无法保存文件: " + ex.getMessage(), "错误", JOptionPane.ERROR_MESSAGE);
            }
        }
    }

    private void undo() {
        try {
            if (undoManager.canUndo()) {
                undoManager.undo();
            }
        } catch (CannotUndoException e) {
            JOptionPane.showMessageDialog(this, "无法撤销操作", "撤销错误", JOptionPane.ERROR_MESSAGE);
        }
    }

    private void redo() {
        try {
            if (undoManager.canRedo()) {
                undoManager.redo();
            }
        } catch (CannotRedoException e) {
            JOptionPane.showMessageDialog(this, "无法重做操作", "重做错误", JOptionPane.ERROR_MESSAGE);
        }
    }

    private void changeFont() {
        Font selectedFont = JFontChooser.showDialog(this, "选择字体", currentFont);
        if (selectedFont != null) {
            currentFont = selectedFont;
            textArea.setFont(currentFont);
        }
    }

    private void changeColor() {
        Color selectedColor = JColorChooser.showDialog(this, "选择颜色", currentColor);
        if (selectedColor != null) {
            currentColor = selectedColor;
            textArea.setForeground(currentColor);
        }
    }

    private void setLineSpacing(float lineSpacing) {
        try {
            StyledDocument doc = (StyledDocument) textArea.getDocument();
            SimpleAttributeSet attrs = new SimpleAttributeSet();
            StyleConstants.setLineSpacing(attrs, lineSpacing - 1.0f);
            doc.setParagraphAttributes(0, doc.getLength(), attrs, false);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    private void findText() {
        String findText = JOptionPane.showInputDialog(this, "查找内容:", "查找", JOptionPane.QUESTION_MESSAGE);
        if (findText != null && !findText.isEmpty()) {
            String content = textArea.getText();
            int start = textArea.getSelectionEnd();
            int index = content.indexOf(findText, start);
            if (index == -1 && start != 0) {
                index = content.indexOf(findText, 0);
            }
            if (index != -1) {
                textArea.setCaretPosition(index + findText.length());
                textArea.select(index, index + findText.length());
            } else {
                JOptionPane.showMessageDialog(this, "找不到 \"" + findText + "\"", "查找", JOptionPane.INFORMATION_MESSAGE);
            }
        }
    }

    private void replaceText() {
        String[] inputs = new String[2];
        JTextField findField = new JTextField();
        JTextField replaceField = new JTextField();
        Object[] message = {
                "查找内容:", findField,
                "替换为:", replaceField
        };
        int option = JOptionPane.showConfirmDialog(this, message, "替换", JOptionPane.OK_CANCEL_OPTION);
        if (option == JOptionPane.OK_OPTION) {
            String findText = findField.getText();
            String replaceText = replaceField.getText();
            if (!findText.isEmpty()) {
                String content = textArea.getText();
                String newContent = content.replace(findText, replaceText);
                textArea.setText(newContent);
            }
        }
    }

    private boolean checkUnsavedChanges() {
        return true; // 简化实现，实际应该检查文本是否修改
    }

    public static void main(String[] args) {
        SwingUtilities.invokeLater(TextEditor::new);
    }
}    